package redis

import (
	"context"
	"time"

	"github.com/go-redis/redis/v8"
)

// Cache Redis 缓存封装
type Cache struct {
	client *redis.Client
	ctx    context.Context
}

// NewCache 创建 Redis 缓存实例
func NewCache() Cache {
	return Cache{
		client: GetClient(),
		ctx:    GetContext(),
	}
}

// GetClient 获取原始 Redis 客户端
func (c *Cache) GetClient() *redis.Client {
	return c.client
}

// GetContext 获取 Redis 上下文
func (c *Cache) GetContext() context.Context {
	return c.ctx
}

// Close 关闭 Redis 连接
func (c *Cache) Close() error {
	if c.client == nil {
		return nil
	}
	return c.client.Close()
}

// String 操作封装

// Set 设置字符串值
func (c *Cache) Set(key string, value interface{}, expiration time.Duration) error {
	return c.client.Set(c.ctx, key, value, expiration).Err()
}

// Get 获取字符串值
func (c *Cache) Get(key string) (string, error) {
	return c.client.Get(c.ctx, key).Result()
}

// Del 删除键
func (c *Cache) Del(keys ...string) error {
	return c.client.Del(c.ctx, keys...).Err()
}

// Exists 检查键是否存在
func (c *Cache) Exists(key string) (bool, error) {
	count, err := c.client.Exists(c.ctx, key).Result()
	return count > 0, err
}

// Expire 设置过期时间
func (c *Cache) Expire(key string, expiration time.Duration) error {
	return c.client.Expire(c.ctx, key, expiration).Err()
}

// TTL 获取剩余过期时间
func (c *Cache) TTL(key string) (time.Duration, error) {
	return c.client.TTL(c.ctx, key).Result()
}

// Hash 操作封装

// HSet 设置哈希字段
func (c *Cache) HSet(key string, values ...interface{}) error {
	return c.client.HSet(c.ctx, key, values...).Err()
}

// HGet 获取哈希字段值
func (c *Cache) HGet(key, field string) (string, error) {
	return c.client.HGet(c.ctx, key, field).Result()
}

// HGetAll 获取所有哈希字段
func (c *Cache) HGetAll(key string) (map[string]string, error) {
	return c.client.HGetAll(c.ctx, key).Result()
}

// HDel 删除哈希字段
func (c *Cache) HDel(key string, fields ...string) error {
	return c.client.HDel(c.ctx, key, fields...).Err()
}

// List 操作封装

// LPush 从左边推入
func (c *Cache) LPush(key string, values ...interface{}) error {
	return c.client.LPush(c.ctx, key, values...).Err()
}

// RPush 从右边推入
func (c *Cache) RPush(key string, values ...interface{}) error {
	return c.client.RPush(c.ctx, key, values...).Err()
}

// LPop 从左边弹出
func (c *Cache) LPop(key string) (string, error) {
	return c.client.LPop(c.ctx, key).Result()
}

// RPop 从右边弹出
func (c *Cache) RPop(key string) (string, error) {
	return c.client.RPop(c.ctx, key).Result()
}

// LLen 获取列表长度
func (c *Cache) LLen(key string) (int64, error) {
	return c.client.LLen(c.ctx, key).Result()
}

// Set 操作封装

// SAdd 添加集合成员
func (c *Cache) SAdd(key string, members ...interface{}) error {
	return c.client.SAdd(c.ctx, key, members...).Err()
}

// SRem 删除集合成员
func (c *Cache) SRem(key string, members ...interface{}) error {
	return c.client.SRem(c.ctx, key, members...).Err()
}

// SMembers 获取集合所有成员
func (c *Cache) SMembers(key string) ([]string, error) {
	return c.client.SMembers(c.ctx, key).Result()
}

// SIsMember 检查是否是集合成员
func (c *Cache) SIsMember(key string, member interface{}) (bool, error) {
	return c.client.SIsMember(c.ctx, key, member).Result()
}

// 其他常用操作

// Keys 查找匹配的键
func (c *Cache) Keys(pattern string) ([]string, error) {
	return c.client.Keys(c.ctx, pattern).Result()
}

// Ping 检查连接
func (c *Cache) Ping() error {
	return c.client.Ping(c.ctx).Err()
}

// Incr 递增
func (c *Cache) Incr(key string) (int64, error) {
	return c.client.Incr(c.ctx, key).Result()
}

// Decr 递减
func (c *Cache) Decr(key string) (int64, error) {
	return c.client.Decr(c.ctx, key).Result()
}
